<template>
  <div v-if="!element" class="text-red-500">组件不存在</div>
  <a-form-item v-else-if="element.isform" v-bind="element.formItem">
    <component
      :is="component.render(element.props, element, onEvents())"
      :key="element.id"
      :onUpdate:modelValue="onUpdate"
      v-bind="onBind(element)"
    ></component
  ></a-form-item>
  <component
    v-else
    :is="component.render(element.props, element, onEvents())"
    :key="element.id"
    :onUpdate:modelValue="onUpdate"
    v-bind="onBind(element)"
  ></component>
</template>

<script lang="ts">
import { defineComponent, computed, PropType } from "vue";
import { customGlobalComponent } from "@/components/custom";
import type { Container } from "@/components/custom/index.tsx";
import { useVModel } from "@vueuse/core";
import { useFormStore } from "@/store/form.ts";

export default defineComponent({
  name: "DraggableItem",
  props: {
    element: {
      type: Object as PropType<Container>,
      default: () => {},
    },
  },
  emits: ["update:element"],
  setup(props, { emit }) {
    const element = useVModel(props, "element", emit);
    const formStore = useFormStore();
    const component = computed(() => {
      const config = customGlobalComponent()[props.element.name];
      if (!config) {
        return null;
      }
      return config;
    });

    const onUpdate = (value: any) => {
      props.element.props.modelValue = value;
    };
    const onBind = (config: Container) => {
      let obj = {};
      for (const key in props.element.events) {
        obj[key] = (e: any) => {
          let app = formStore.appConfig;
          let fun = new Function(element.value.events[key]).bind({
            e,
            config,
            app,
          });
          fun();
        };
      }

      return obj;
    };
    const onEvents = () => {
      return formStore.appConfig[props.element.id];
    };
    return { element, component, onUpdate, onBind, onEvents };
  },
});
</script>

<style lang="scss" scoped></style>
